home *** CD-ROM | disk | FTP | other *** search
/ Personal Computer World 2005 October / PCWOCT05.iso / Software / FromTheMag / XAMPP 1.4.14 / xampp-win32-1.4.14-installer.exe / xampp / php / pear / Auth / Container / MDB.php < prev    next >
PHP Script  |  2004-03-24  |  12KB  |  392 lines

  1. <?php
  2. //
  3. // +----------------------------------------------------------------------+
  4. // | PHP Version 4                                                        |
  5. // +----------------------------------------------------------------------+
  6. // |                                                                      |
  7. // +----------------------------------------------------------------------+
  8. // | This source file is subject to version 2.02 of the PHP license,      |
  9. // | that is bundled with this package in the file LICENSE, and is        |
  10. // | available at through the world-wide-web at                           |
  11. // | http://www.php.net/license/2_02.txt.                                 |
  12. // | If you did not receive a copy of the PHP license and are unable to   |
  13. // | obtain it through the world-wide-web, please send a note to          |
  14. // | license@php.net so we can mail you a copy immediately.               |
  15. // +----------------------------------------------------------------------+
  16. // | Author: Lorenzo Alberton <l.alberton@quipo.it>                                  |
  17. // +----------------------------------------------------------------------+
  18. //
  19. // $Id: MDB.php,v 1.12 2003/10/13 08:08:45 yavo Exp $
  20. //
  21.  
  22. require_once 'Auth/Container.php';
  23. require_once 'MDB.php';
  24.  
  25. /**
  26.  * Storage driver for fetching login data from a database
  27.  *
  28.  * This storage driver can use all databases which are supported
  29.  * by the PEAR MDB abstraction layer to fetch login data.
  30.  *
  31.  * @author   Lorenzo Alberton <l.alberton@quipo.it>
  32.  * @package  Auth
  33.  * @version  $Revision: 1.12 $
  34.  */
  35. class Auth_Container_MDB extends Auth_Container
  36. {
  37.  
  38.     /**
  39.      * Additional options for the storage container
  40.      * @var array
  41.      */
  42.     var $options = array();
  43.  
  44.     /**
  45.      * DB object
  46.      * @var object
  47.      */
  48.     var $db = null;
  49.     var $dsn = '';
  50.  
  51.     /**
  52.      * User that is currently selected from the DB.
  53.      * @var string
  54.      */
  55.     var $activeUser = '';
  56.  
  57.     // {{{ Constructor
  58.  
  59.     /**
  60.      * Constructor of the container class
  61.      *
  62.      * Initate connection to the database via PEAR::DB
  63.      *
  64.      * @param  string Connection data or DB object
  65.      * @return object Returns an error object if something went wrong
  66.      */
  67.     function Auth_Container_MDB($dsn)
  68.     {
  69.         $this->_setDefaults();
  70.  
  71.         if (is_array($dsn)) {
  72.             $this->_parseOptions($dsn);
  73.             if (empty($this->options['dsn'])) {
  74.                 PEAR::raiseError('No connection parameters specified!');
  75.             }
  76.         } else {
  77.             $this->options['dsn'] = $dsn;
  78.         }
  79.     }
  80.  
  81.     // }}}
  82.     // {{{ _connect()
  83.  
  84.     /**
  85.      * Connect to database by using the given DSN string
  86.      *
  87.      * @access private
  88.      * @param  string DSN string
  89.      * @return mixed  Object on error, otherwise bool
  90.      */
  91.     function _connect($dsn)
  92.     {
  93.         if (is_string($dsn) || is_array($dsn)) {
  94.             $this->db =& MDB::Connect($dsn);
  95.         } elseif (get_parent_class($dsn) == "mdb_common") {
  96.             $this->db = $dsn;
  97.         } elseif (is_object($dsn) && MDB::isError($dsn)) {
  98.             return PEAR::raiseError($dsn->getMessage(), $dsn->code);
  99.         } else {
  100.             return PEAR::raiseError('The given dsn was not valid in file ' . __FILE__ . ' at line ' . __LINE__,
  101.                                     41,
  102.                                     PEAR_ERROR_RETURN,
  103.                                     null,
  104.                                     null
  105.                                     );
  106.  
  107.         }
  108.  
  109.         if (MDB::isError($this->db) || PEAR::isError($this->db)) {
  110.             return PEAR::raiseError($this->db->getMessage(), $this->db->code);
  111.         } else {
  112.             return true;
  113.         }
  114.     }
  115.  
  116.     // }}}
  117.     // {{{ _prepare()
  118.  
  119.     /**
  120.      * Prepare database connection
  121.      *
  122.      * This function checks if we have already opened a connection to
  123.      * the database. If that's not the case, a new connection is opened.
  124.      *
  125.      * @access private
  126.      * @return mixed True or a DB error object.
  127.      */
  128.     function _prepare()
  129.     {
  130.         return $this->_connect($this->options['dsn']);
  131.     }
  132.  
  133.     // }}}
  134.     // {{{ query()
  135.  
  136.     /**
  137.      * Prepare query to the database
  138.      *
  139.      * This function checks if we have already opened a connection to
  140.      * the database. If that's not the case, a new connection is opened.
  141.      * After that the query is passed to the database.
  142.      *
  143.      * @access public
  144.      * @param  string Query string
  145.      * @return mixed  a MDB_result object or MDB_OK on success, a MDB
  146.      *                or PEAR error on failure
  147.      */
  148.     function query($query)
  149.     {
  150.         $err = $this->_prepare();
  151.         if ($err !== true) {
  152.             return $err;
  153.         }
  154.         return $this->db->query($query);
  155.     }
  156.  
  157.     // }}}
  158.     // {{{ _setDefaults()
  159.  
  160.     /**
  161.      * Set some default options
  162.      *
  163.      * @access private
  164.      * @return void
  165.      */
  166.     function _setDefaults()
  167.     {
  168.         $this->options['table']       = 'auth';
  169.         $this->options['usernamecol'] = 'username';
  170.         $this->options['passwordcol'] = 'password';
  171.         $this->options['dsn']         = '';
  172.         $this->options['db_fields']   = '';
  173.         $this->options['cryptType']   = 'md5';
  174.     }
  175.  
  176.     // }}}
  177.     // {{{ _parseOptions()
  178.  
  179.     /**
  180.      * Parse options passed to the container class
  181.      *
  182.      * @access private
  183.      * @param  array
  184.      */
  185.     function _parseOptions($array)
  186.     {
  187.         foreach ($array as $key => $value) {
  188.             if (isset($this->options[$key])) {
  189.                 $this->options[$key] = $value;
  190.             }
  191.         }
  192.  
  193.         // Include additional fields if they exist
  194.         if (!empty($this->options['db_fields'])) {
  195.             if (is_array($this->options['db_fields'])) {
  196.                 $this->options['db_fields'] = join($this->options['db_fields'], ', ');
  197.             }
  198.             $this->options['db_fields'] = ', ' . $this->options['db_fields'];
  199.         }
  200.  
  201.     }
  202.  
  203.     // }}}
  204.     // {{{ fetchData()
  205.  
  206.     /**
  207.      * Get user information from database
  208.      *
  209.      * This function uses the given username to fetch
  210.      * the corresponding login data from the database
  211.      * table. If an account that matches the passed username
  212.      * and password is found, the function returns true.
  213.      * Otherwise it returns false.
  214.      *
  215.      * @param   string Username
  216.      * @param   string Password
  217.      * @return  mixed  Error object or boolean
  218.      */
  219.     function fetchData($username, $password)
  220.     {
  221.         // Prepare for a database query
  222.         $err = $this->_prepare();
  223.         if ($err !== true) {
  224.             return PEAR::raiseError($err->getMessage(), $err->getCode());
  225.         }
  226.  
  227.         // Find if db_fileds contains a *, i so assume all col are selected
  228.         if (strstr($this->options['db_fields'], '*')) {
  229.             $sql_from = '*';
  230.         } else{
  231.             $sql_from = $this->options['usernamecol'] . ', '. $this->options['passwordcol'] . $this->options['db_fields'];
  232.         }
  233.  
  234.         $query = sprintf("SELECT %s FROM %s WHERE %s = %s",
  235.                          $sql_from,
  236.                          $this->options['table'],
  237.                          $this->options['usernamecol'],
  238.                          $this->db->getTextValue($username)
  239.                          );
  240.  
  241.         $res = $this->db->getRow($query, null, null, null, MDB_FETCHMODE_ASSOC);
  242.  
  243.         if (MDB::isError($res) || PEAR::isError($res)) {
  244.             return PEAR::raiseError($res->getMessage(), $res->getCode());
  245.         }
  246.         if (!is_array($res)) {
  247.             $this->activeUser = '';
  248.             return false;
  249.         }
  250.         if ($this->verifyPassword(trim($password, "\r\n"),
  251.                                   trim($res[$this->options['passwordcol']], "\r\n"),
  252.                                   $this->options['cryptType'])) {
  253.             // Store additional field values in the session
  254.             foreach ($res as $key => $value) {
  255.                 if ($key == $this->options['passwordcol'] ||
  256.                     $key == $this->options['usernamecol']) {
  257.                     continue;
  258.                 }
  259.                 // Use reference to the auth object if exists
  260.                 // This is because the auth session variable can change so a static call to setAuthData does not make sence
  261.                 if(is_object($this->_auth_obj)){
  262.                     $this->_auth_obj->setAuthData($key, $value);
  263.                 } else {
  264.                     Auth::setAuthData($key, $value);
  265.                 }
  266.             }
  267.  
  268.             return true;
  269.         }
  270.  
  271.         $this->activeUser = $res[$this->options['usernamecol']];
  272.         return false;
  273.     }
  274.  
  275.     // }}}
  276.     // {{{ listUsers()
  277.  
  278.     function listUsers()
  279.     {
  280.         $err = $this->_prepare();
  281.         if ($err !== true) {
  282.             return PEAR::raiseError($err->getMessage(), $err->getCode());
  283.         }
  284.  
  285.         $retVal = array();
  286.  
  287.         // Find if db_fileds contains a *, i so assume all col are selected
  288.         if (strstr($this->options['db_fields'], '*')) {
  289.             $sql_from = '*';
  290.         } else{
  291.             $sql_from = $this->options['db_fields'];
  292.         }
  293.  
  294.         $query = sprintf('SELECT %s FROM %s',
  295.                          $sql_from,
  296.                          $this->options['table']
  297.                          );
  298.  
  299.         $res = $this->db->getAll($query, null, null, null, MDB_FETCHMODE_ASSOC);
  300.  
  301.         if (MDB::isError($res)) {
  302.             return PEAR::raiseError($res->getMessage(), $res->getCode());
  303.         } else {
  304.             foreach ($res as $user) {
  305.                 $user['username'] = $user[$this->options['usernamecol']];
  306.                 $retVal[] = $user;
  307.             }
  308.         }
  309.         return $retVal;
  310.     }
  311.  
  312.     // }}}
  313.     // {{{ addUser()
  314.  
  315.     /**
  316.      * Add user to the storage container
  317.      *
  318.      * @access public
  319.      * @param  string Username
  320.      * @param  string Password
  321.      * @param  mixed  Additional information that are stored in the DB
  322.      *
  323.      * @return mixed True on success, otherwise error object
  324.      */
  325.     function addUser($username, $password, $additional = "")
  326.     {
  327.         if (function_exists($this->options['cryptType'])) {
  328.             $cryptFunction = $this->options['cryptType'];
  329.         } else {
  330.             $cryptFunction = 'md5';
  331.         }
  332.  
  333.         $additional_key   = '';
  334.         $additional_value = '';
  335.  
  336.         if (is_array($additional)) {
  337.             foreach ($additional as $key => $value) {
  338.                 $additional_key   .= ', ' . $key;
  339.                 $additional_value .= ', ' . $this->db->getTextValue($value);
  340.             }
  341.         }
  342.  
  343.         $query = sprintf("INSERT INTO %s (%s, %s%s) VALUES (%s, %s%s)",
  344.                          $this->options['table'],
  345.                          $this->options['usernamecol'],
  346.                          $this->options['passwordcol'],
  347.                          $additional_key,
  348.                          $this->db->getTextValue($username),
  349.                          $this->db->getTextValue($cryptFunction($password)),
  350.                          $additional_value
  351.                          );
  352.  
  353.         $res = $this->query($query);
  354.  
  355.         if (MDB::isError($res)) {
  356.             return PEAR::raiseError($res->getMessage(), $res->code);
  357.         } else {
  358.             return true;
  359.         }
  360.     }
  361.  
  362.     // }}}
  363.     // {{{ removeUser()
  364.  
  365.     /**
  366.      * Remove user from the storage container
  367.      *
  368.      * @access public
  369.      * @param  string Username
  370.      *
  371.      * @return mixed True on success, otherwise error object
  372.      */
  373.     function removeUser($username)
  374.     {
  375.         $query = sprintf("DELETE FROM %s WHERE %s = %s",
  376.                          $this->options['table'],
  377.                          $this->options['usernamecol'],
  378.                          $this->db->getTextValue($username)
  379.                          );
  380.  
  381.         $res = $this->query($query);
  382.  
  383.         if (MDB::isError($res)) {
  384.            return PEAR::raiseError($res->getMessage(), $res->code);
  385.         } else {
  386.           return true;
  387.         }
  388.     }
  389.  
  390.     // }}}
  391. }
  392. ?>